#include <vector>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <future>
#include <stdexcept>
#include <iostream>
#include <random>
class ThreadPool {
public:
    // 构造函数：创建指定数量的工作线程，默认使用硬件并发数
    explicit ThreadPool(size_t num_threads = std::thread::hardware_concurrency()) 
        : stop_(false) {
        if (num_threads == 0) throw std::invalid_argument("线程数量必须大于0");
        
        // 创建工作线程，每个线程循环等待并执行任务
        for (size_t i = 0; i < num_threads; ++i) {
            workers_.emplace_back([this] {
                while (true) {  // 线程主循环
                    std::function<void()> task;
                    {
                        // 加锁并等待任务或停止信号
                        std::unique_lock<std::mutex> lock(queue_mutex_);
                        condition_.wait(lock, [this] { 
                            return stop_ || !tasks_.empty(); 
                        });
                        
                        // 若线程池停止且任务队列为空，则退出线程
                        if (stop_ && tasks_.empty()) return;
                        
                        // 取出任务并解锁（允许其他线程操作队列）
                        task = std::move(tasks_.front());
                        tasks_.pop();
                    }
                    task();  // 执行任务（无需持有锁）
                }
            });
        }
    }

    // 禁止拷贝构造和赋值
    ThreadPool(const ThreadPool&) = delete;
    ThreadPool& operator=(const ThreadPool&) = delete;

    // 提交任务并返回future（支持任意参数和返回值类型）
    template<class F, class... Args>
    auto enqueue(F&& f, Args&&... args) 

        -> std::future<typename std::result_of<F(Args...)>::type> {

        using return_type = typename std::result_of<F(Args...)>::type;

        // 包装任务为shared_ptr<packaged_task>以延长生命周期
        auto task = std::make_shared<std::packaged_task<return_type()>>(
            std::bind(std::forward<F>(f), std::forward<Args>(args)...)
        );
        
        std::future<return_type> res = task->get_future();
        {
            std::lock_guard<std::mutex> lock(queue_mutex_);
            
            // 若线程池已停止，禁止提交新任务
            if (stop_) throw std::runtime_error("线程池已停止，无法提交任务");
            
            // 将任务加入队列（lambda捕获task指针）
            tasks_.emplace([task]() { (*task)(); });
        }
        condition_.notify_one();  // 唤醒一个等待的工作线程
        return res;
    }

    // 析构函数：停止所有线程并等待完成
    ~ThreadPool() {
        {
            std::lock_guard<std::mutex> lock(queue_mutex_);
            stop_ = true;  // 设置停止标志
        }
        condition_.notify_all();  // 唤醒所有工作线程
        
        // 等待所有线程结束
        for (std::thread& worker : workers_) {
            if (worker.joinable()) worker.join();
        }
    }

private:
    std::vector<std::thread> workers_;       // 工作线程容器
    std::queue<std::function<void()>> tasks_; // 任务队列（存储无参可调用对象）
    std::mutex queue_mutex_;                 // 保护任务队列的互斥锁
    std::condition_variable condition_;       // 通知线程有新任务的条件变量
    bool stop_;                              // 线程池停止标志
};
void print_num(int i) { std::cout << i << '\n'; }

int return_num(int r) { return 42; }

struct PrintNum {
  void operator()(int i) const { std::cout << i << '\n'; }
};
int main() {
    try {
        // 创建线程池（默认使用硬件支持的并发数，如8核CPU创建8线程）
        ThreadPool pool;
        
        // 提交任务1：无参数，返回int
        auto future1 = pool.enqueue([]() {
            std::this_thread::sleep_for(std::chrono::seconds(1));
            return 42;
        });
        
        // 提交任务2：带参数，返回string
        auto future2 = pool.enqueue([](const std::string& msg, int x) {
            return msg + std::to_string(x);
        }, "结果：", 100);
        //void 类型测试
        auto future3 = pool.enqueue([]() {
            std::this_thread::sleep_for(std::chrono::seconds(1));
            std::cout << "任务3完成" << std::endl;
        });
        std::cout << "任务3结果：" <<"ss"<< std::endl;
       ; // 等待任务3完成    
        // 获取结果（会阻塞直到任务完成）
        std::cout << "任务1结果：" << future1.get() << std::endl;  // 输出42
        std::cout << "任务2结果：" << future2.get() << std::endl;  // 输出"结果：100"
          std::function<void()> f_display_42 = []() { print_num(42); };
          std::cout << std::random_device{}() << std::endl;
             std::random_device rd;       // 定义随机设备
    std::cout << rd() << std::endl; // 调用它一次
          std::function<int(int)> f_return_42 = return_num;
    } catch (const std::exception& e) {
        std::cerr << "错误：" << e.what() << std::endl;
    }
    return 0;
}